
package cribbage.client;

import com.samskivert.swing.HGroupLayout;
import com.samskivert.swing.Label;
import com.samskivert.swing.LabelStyleConstants;
import com.samskivert.swing.MultiLineLabel;
import com.samskivert.swing.VGroupLayout;

import com.threerings.crowd.client.PlaceView;
import com.threerings.crowd.data.PlaceObject;
import com.threerings.parlor.card.data.*;
import com.threerings.presents.dobj.AttributeChangeListener;
import com.threerings.presents.dobj.AttributeChangedEvent;
import com.threerings.presents.dobj.ElementUpdateListener;
import com.threerings.presents.dobj.ElementUpdatedEvent;
import com.threerings.toybox.util.ToyBoxContext;
import com.threerings.util.MessageBundle;
import com.threerings.util.Name;

import cribbage.data.CribbageCodes;
import cribbage.data.CribbageObject;

import java.awt.Color;
import java.awt.Dimension;
import java.awt.Font;

import javax.swing.JPanel;
import javax.swing.JProgressBar;

public class CribbageTableView extends JPanel
      implements
         PlaceView,
         AttributeChangeListener,
         ElementUpdateListener,
         CribbageCodes {

   private static final Font ACTION_FONT = new Font("Arial", Font.BOLD, 16);

   private static final int SCORE_WIDTH = 40;

   private Name myName;

   private CribbageObject _obj;

   private MessageBundle _msgs;

   protected HandPanel myHandArea, theirHandArea, inPlayArea, cribArea;

   private DeckPanel deckArea;

   private JPanel scoreArea, myScoreArea, theirScoreArea;

   // private VirtualMediaPanel board;

   private JProgressBar myScoreBar, theirScoreBar;

   private MultiLineLabel myScore, theirScore;

   // private BufferedMirage boardImage, meter1, meter2;

   private int myPlayerIndex;

   public CribbageTableView (ToyBoxContext ctx) {
      super(new HGroupLayout(HGroupLayout.STRETCH));

      _msgs = ctx.getMessageManager().getBundle(CribbageCodes.CRIBBAGE_MSG_BUNDLE);

      myName = ctx.getUsername();

      myHandArea = new HandPanel(ctx, false, HandPanel.feltColor);
      theirHandArea = new HandPanel(ctx, true, HandPanel.feltColor);
      inPlayArea = new HandPanel(ctx, true, new Color(0xC80D0D));
      deckArea = new DeckPanel(ctx);
      cribArea = new HandPanel(ctx, true, new Color(0x400080));
      scoreArea = HGroupLayout.makeHBox(HGroupLayout.STRETCH, HGroupLayout.LEFT,
            HGroupLayout.STRETCH);
      /*
       * 
       * board = new VirtualMediaPanel(ctx.getFrameManager()) { @Override public
       * void doLayout() { super.doLayout(); System.out.println("board dim: " +
       * board.getWidth() + " x " + board.getHeight()); AffineTransform tx = new
       * AffineTransform(); tx.scale(((double) board.getWidth()) /
       * boardImage.getWidth(), ((double) board.getHeight()) /
       * boardImage.getHeight()); setBackground(new
       * TransformedMirage(boardImage, tx)); } };
       */

      HGroupLayout layout = (HGroupLayout) getLayout();
      layout.setOffAxisPolicy(HGroupLayout.STRETCH);
      layout.setJustification(HGroupLayout.LEFT);
      // layout.setGap(0);

      JPanel cardArea = VGroupLayout.makeVBox(VGroupLayout.STRETCH, VGroupLayout.TOP,
            VGroupLayout.STRETCH);
      ((VGroupLayout) cardArea.getLayout()).setGap(0);

      JPanel deckAndCrib = VGroupLayout.makeVBox(VGroupLayout.STRETCH, VGroupLayout.TOP,
            VGroupLayout.STRETCH);
      ((VGroupLayout) deckAndCrib.getLayout()).setGap(0);

      /*
       * meter1 = new
       * BufferedMirage(ctx.loadImage("media/meters.png").getSubimage(0, 0, 14,
       * 1)); meter2 = new
       * BufferedMirage(ctx.loadImage("media/meters.png").getSubimage(0, 1, 14,
       * 1)); boardImage = new BufferedMirage(ctx.loadImage("media/board.png"));
       * board.setPreferredSize(new Dimension(60, 400));
       * board.setBackground(boardImage);
       */
      // scoreArea.setPreferredSize(new Dimension(70,400));
      myScoreBar = new JProgressBar(JProgressBar.VERTICAL, 0, 120);
      myScore = new MultiLineLabel("0");
      myScoreBar.setPreferredSize(new Dimension(SCORE_WIDTH - 10, 300));
      myScore.setPreferredSize(new Dimension(SCORE_WIDTH, 100));
      myScoreBar.setForeground(Color.BLUE);

      theirScoreBar = new JProgressBar(JProgressBar.VERTICAL, 0, 120);
      theirScore = new MultiLineLabel("0");
      theirScoreBar.setPreferredSize(new Dimension(SCORE_WIDTH - 10, 300));
      theirScore.setPreferredSize(new Dimension(SCORE_WIDTH, 100));
      theirScoreBar.setForeground(Color.RED);

      myScoreArea = VGroupLayout.makeVBox(VGroupLayout.STRETCH, VGroupLayout.TOP,
            VGroupLayout.STRETCH);
      theirScoreArea = VGroupLayout.makeVBox(VGroupLayout.STRETCH, VGroupLayout.TOP,
            VGroupLayout.STRETCH);

      deckArea.setHand(10);
      deckArea.setHandLocation(deckArea.getWidth() / 2, deckArea.getHeight() / 2
            - deckArea.getBigHeight() / 2);
      deckArea.setPreferredSize(new Dimension(140, 300));

      cribArea.setHand(0);
      cribArea.setHandLocation(deckArea.getWidth() / 2, deckArea.getHeight() / 2
            - deckArea.getBigHeight() / 2);
      cribArea.setPreferredSize(new Dimension(140, 150));

      theirHandArea.setPreferredSize(new Dimension(200, 150));
      // theirHandArea.setMaximumSize(new Dimension(200,150));

      inPlayArea.setPreferredSize(new Dimension(200, 150));
      // inPlayArea.setMinimumSize(new Dimension(200,150));

      myHandArea.setSelectableCardOffset(3);
      myHandArea.setSelectedCardOffset(10);
      myHandArea.setPreferredSize(new Dimension(200, 150));
      // myHandArea.setMaximumSize(new Dimension(200,150));

      JPanel table = HGroupLayout.makeHBox(HGroupLayout.STRETCH, HGroupLayout.LEFT,
            HGroupLayout.STRETCH);
      ((HGroupLayout) table.getLayout()).setGap(0);

      myScoreArea.add(myScoreBar);
      myScoreArea.add(myScore, VGroupLayout.FIXED);
      myScoreArea.add(new MultiLineLabel("Me"), VGroupLayout.FIXED);
      theirScoreArea.add(theirScoreBar);
      theirScoreArea.add(theirScore, VGroupLayout.FIXED);
      theirScoreArea.add(new MultiLineLabel("Them"), VGroupLayout.FIXED);
      scoreArea.add(myScoreArea);
      scoreArea.add(theirScoreArea);

      cardArea.add(theirHandArea);
      cardArea.add(inPlayArea);
      cardArea.add(myHandArea);
      deckAndCrib.add(deckArea);
      deckAndCrib.add(cribArea);

      table.add(deckAndCrib, HGroupLayout.FIXED);
      table.add(cardArea);

      MultiLineLabel l = new MultiLineLabel("Score");
      l.setFont(ACTION_FONT);
      JPanel p = VGroupLayout
            .makeVBox(VGroupLayout.STRETCH, VGroupLayout.TOP, VGroupLayout.STRETCH);
      p.add(l, VGroupLayout.FIXED);
      p.add(scoreArea);

      // add(board, HGroupLayout.FIXED);
      // add(scoreArea, HGroupLayout.FIXED);
      add(p, HGroupLayout.FIXED);
      add(table);

      p.setBackground(new Color(0xDAEB9C));
      scoreArea.setBackground(new Color(0xDAEB9C));
      myScoreArea.setBackground(new Color(0xDAEB9C));
      theirScoreArea.setBackground(new Color(0xDAEB9C));
      setBackground(new Color(0xDAEB9C));
   }

   @Override
   public Dimension getPreferredSize () {
      return new Dimension(600, 450);
   }

   @Override
   public void doLayout () {
      super.doLayout();

   }

   public void willEnterPlace (PlaceObject plobj) {
      _obj = (CribbageObject) plobj;
      _obj.addListener(this);
      myPlayerIndex = _obj.getPlayerIndex(myName);
   }

   public void didLeavePlace (PlaceObject plobj) {
      if (_obj != null) {
         _obj.removeListener(this);
         _obj = null;
      }
   }

   public void gameDidStart () {

   }

   public void receivedHand (Hand h) {
      myHandArea.setHand(h);
   }

   public void attributeChanged (AttributeChangedEvent event) {
      String name = event.getName();

      if (name.equals(CribbageObject.WINNERS)) {
         int winnerIndex = _obj.getWinnerIndex();
         if (winnerIndex >= 0) {
            showText(_msgs.get("m.winner"), ACTION_FONT, Color.green, getWidth() / 2,
                  getHeight() / 2);
         }
      } else if (name.equals(CribbageObject.HAND_SIZES)) {
         // Whole hand array changed, update other hands, ours is set by
         // handReceived
         int [] handSizes = _obj.getHandSizes();
         // for (int i = 0; i < handSizes.length; i++)
         // if (i != myPlayerIndex)

         /** NOTE: This only works for two-player game! */
         theirHandArea.setHand(handSizes[1 - myPlayerIndex]);
      } else if (name.equals(CribbageObject.UPCARD)) {
         deckArea.setUpcard(_obj.getUpCard());
      }

   }

   public void elementUpdated (ElementUpdatedEvent event) {
      String name = event.getName();

      if (name.equals(CribbageObject.HAND_SIZES)) {
         if (event.getIndex() != myPlayerIndex)
            theirHandArea.setHand(_obj.getHandSize(event.getIndex()));
      }
   }

   public void turnDidChange (Name turnHolder, boolean ourTurn) {
      int phase = _obj.turnPhase;
      if (!ourTurn) {
         myHandArea.setHandSelectionMode(HandPanel.NONE);
      } else if (phase == MAKE_CRIB) {
         myHandArea.setHandSelectionMode(HandPanel.MULTIPLE);
      } else if (phase == NORMAL_PLAY) {
         myHandArea.setHandSelectionMode(HandPanel.SINGLE);
      } else if (phase == SCORING) {
         myHandArea.setHandSelectionMode(HandPanel.NONE);
      }
   }

   private void showText (String message, Font font, Color color, int x, int y) {
      Label label = new Label(message, LabelStyleConstants.OUTLINE | LabelStyleConstants.SHADOW,
            color, Color.black, font);
      label.layout(this);
   }

   public void playCards () {
      myHandArea.playCards();
   }
}
